/* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
import { MockttpServer } from 'mockttp';
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { DAPP_URL, WINDOW_TITLES } from '../../../constants';
import { loginWithBalanceValidation } from '../../../page-objects/flows/login.flow';
import TestDapp from '../../../page-objects/pages/test-dapp';
import { TRANSACTION_DATA_UNISWAP } from '../../../../data/confirmations/transaction-decode';
import TransactionConfirmation from '../../../page-objects/pages/confirmations/redesign/transaction-confirmation';
import ContractAddressRegistry from '../../../seeder/contract-address-registry';
import { TestSuiteArguments } from './shared';

const { withFixtures } = require('../../../helpers');
const FixtureBuilder = require('../../../fixtures/fixture-builder');
const { SMART_CONTRACTS } = require('../../../seeder/smart-contracts');

describe('Confirmation Redesign Contract Interaction Transaction Decoding', function () {
  const smartContract = SMART_CONTRACTS.NFTS;

  describe('Create a mint nft transaction', function () {
    it(`decodes 4 bytes transaction data`, async function () {
      await withFixtures(
        {
          dappOptions: { numberOfTestDapps: 1 },
          fixtures: new FixtureBuilder()
            .withPermissionControllerConnectedToTestDapp()
            .build(),
          testSpecificMock: mocked4BytesResponse,
          smartContract,
          title: this.test?.fullTitle(),
        },
        async ({
          driver,
          contractRegistry,
          localNodes,
        }: TestSuiteArguments) => {
          await loginWithBalanceValidation(driver, localNodes?.[0]);
          const contractAddress = await (
            contractRegistry as ContractAddressRegistry
          ).getContractAddress(smartContract);

          const testDapp = new TestDapp(driver);
          const confirmation = new TransactionConfirmation(driver);

          await testDapp.openTestDappPage({ contractAddress, url: DAPP_URL });

          await testDapp.clickERC721MintButton();

          await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
          await confirmation.checkPageIsLoaded();
          await confirmation.clickAdvancedDetailsButton();
          await confirmation.clickScrollToBottomButton();
          await confirmation.verifyAdvancedDetailsIsDisplayed('4Bytes');
        },
      );
    });
  });

  it(`decodes Sourcify transaction data`, async function () {
    await withFixtures(
      {
        dappOptions: { numberOfTestDapps: 1 },
        fixtures: new FixtureBuilder()
          .withPermissionControllerConnectedToTestDapp()
          .build(),
        testSpecificMock: mockedSourcifyResponse,
        smartContract,
        title: this.test?.fullTitle(),
      },
      async ({ driver, contractRegistry, localNodes }: TestSuiteArguments) => {
        await loginWithBalanceValidation(driver, localNodes?.[0]);
        const contractAddress = await (
          contractRegistry as ContractAddressRegistry
        ).getContractAddress(smartContract);

        const testDapp = new TestDapp(driver);
        const confirmation = new TransactionConfirmation(driver);

        await testDapp.openTestDappPage({ contractAddress, url: DAPP_URL });

        await testDapp.clickERC721MintButton();
        await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);

        await confirmation.checkPageIsLoaded();
        await confirmation.clickAdvancedDetailsButton();
        await confirmation.clickScrollToBottomButton();
        await confirmation.verifyAdvancedDetailsIsDisplayed('Sourcify');
      },
    );
  });

  it(`falls back to raw hexadecimal when no data is retreived`, async function () {
    await withFixtures(
      {
        dappOptions: { numberOfTestDapps: 1 },
        fixtures: new FixtureBuilder()
          .withPermissionControllerConnectedToTestDapp()
          .build(),
        smartContract,
        title: this.test?.fullTitle(),
      },
      async ({ driver, contractRegistry, localNodes }: TestSuiteArguments) => {
        await loginWithBalanceValidation(driver, localNodes?.[0]);
        const contractAddress = await (
          contractRegistry as ContractAddressRegistry
        ).getContractAddress(smartContract);

        const testDapp = new TestDapp(driver);
        const confirmation = new TransactionConfirmation(driver);

        await testDapp.openTestDappPage({ contractAddress, url: DAPP_URL });

        await testDapp.clickERC721MintButton();
        await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);

        await confirmation.checkPageIsLoaded();
        await confirmation.clickAdvancedDetailsButton();
        await confirmation.clickScrollToBottomButton();
        await confirmation.verifyAdvancedDetailsHexDataIsDisplayed(
          '0x3b4b13810000000000000000000000000000000000000000000000000000000000000001',
        );
      },
    );
  });

  it(`decodes uniswap transaction data`, async function () {
    await withFixtures(
      {
        dappOptions: { numberOfTestDapps: 1 },
        fixtures: new FixtureBuilder()
          .withNetworkControllerOnMainnet()
          .withEnabledNetworks({
            eip155: {
              [CHAIN_IDS.MAINNET]: true,
            },
          })
          .withPermissionControllerConnectedToTestDapp()
          .build(),
        testSpecificMock: mockTokensAndInfura,
        title: this.test?.fullTitle(),
      },
      async ({ driver, localNodes }: TestSuiteArguments) => {
        const addresses = await localNodes?.[0]?.getAccounts();
        const publicAddress = addresses?.[0] as string;

        await loginWithBalanceValidation(driver, localNodes?.[0]);
        const contractAddress = '0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B';

        const confirmation = new TransactionConfirmation(driver);

        const transaction = {
          data: TRANSACTION_DATA_UNISWAP,
          to: contractAddress,
          from: publicAddress,
        };
        await driver.openNewPage(
          `${DAPP_URL}/request?method=eth_sendTransaction&params=${JSON.stringify([transaction])}`,
        );

        await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);

        await confirmation.checkPageIsLoaded();
        await confirmation.clickAdvancedDetailsButton();
        await confirmation.clickScrollToBottomButton();
        await confirmation.verifyUniswapDecodedTransactionAdvancedDetails();
      },
    );
  });
});

async function mocked4BytesResponse(mockServer: MockttpServer) {
  return await mockServer
    .forGet('https://www.4byte.directory/api/v1/signatures/')
    // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
    // eslint-disable-next-line @typescript-eslint/naming-convention
    .withQuery({ hex_signature: '0x3b4b1381' })
    .always()
    .thenCallback(() => ({
      statusCode: 200,
      json: {
        count: 1,
        next: null,
        previous: null,
        results: [
          {
            id: 1,
            // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
            // eslint-disable-next-line @typescript-eslint/naming-convention
            created_at: '2021-09-14T02:07:09.805000Z',
            // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
            // eslint-disable-next-line @typescript-eslint/naming-convention
            text_signature: 'mintNFTs(uint256)',
            // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
            // eslint-disable-next-line @typescript-eslint/naming-convention
            hex_signature: '0x3b4b1381',
            // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860
            // eslint-disable-next-line @typescript-eslint/naming-convention
            bytes_signature: ';K\u0013',
          },
        ],
      },
    }));
}

const SOURCIFY_RESPONSE = {
  files: [
    {
      name: 'metadata.json',
      path: 'contracts/partial_match/11155111/0x076146c765189d51bE3160A2140cF80BFC73ad68/metadata.json',
      content:
        '{"compiler":{"version":"0.8.18+commit.87f61d96"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintNFTs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"events":{"Approval(address,address,uint256)":{"details":"Emitted when `owner` enables `approved` to manage the `tokenId` token."},"ApprovalForAll(address,address,bool)":{"details":"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"Transfer(address,address,uint256)":{"details":"Emitted when `tokenId` token is transferred from `from` to `to`."}},"kind":"dev","methods":{"approve(address,uint256)":{"details":"See {IERC721-approve}."},"balanceOf(address)":{"details":"See {IERC721-balanceOf}."},"getApproved(uint256)":{"details":"See {IERC721-getApproved}."},"isApprovedForAll(address,address)":{"details":"See {IERC721-isApprovedForAll}."},"name()":{"details":"See {IERC721Metadata-name}."},"ownerOf(uint256)":{"details":"See {IERC721-ownerOf}."},"safeTransferFrom(address,address,uint256)":{"details":"See {IERC721-safeTransferFrom}."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"See {IERC721-safeTransferFrom}."},"setApprovalForAll(address,bool)":{"details":"See {IERC721-setApprovalForAll}."},"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."},"symbol()":{"details":"See {IERC721Metadata-symbol}."},"tokenURI(uint256)":{"details":"See {IERC721Metadata-tokenURI}."},"transferFrom(address,address,uint256)":{"details":"See {IERC721-transferFrom}."}},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"contracts/TestDappCollectibles.sol":"TestDappNFTs"},"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"@openzeppelin/contracts/token/ERC721/ERC721.sol":{"keccak256":"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff","license":"MIT","urls":["bzz-raw://7063b5c98711a98018ba4635ac74cee1c1cfa2ea01099498e062699ed9530005","dweb:/ipfs/QmeJ8rGXkcv7RrqLdAW8PCXPAykxVsddfYY6g5NaTwmRFE"]},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"keccak256":"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266","license":"MIT","urls":["bzz-raw://7e66dfde185df46104c11bc89d08fa0760737aa59a2b8546a656473d810a8ea4","dweb:/ipfs/QmXvyqtXPaPss2PD7eqPoSao5Szm2n6UMoiG8TZZDjmChR"]},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"keccak256":"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da","license":"MIT","urls":["bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708","dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"]},"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9","license":"MIT","urls":["bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146","dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"]},"@openzeppelin/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","license":"MIT","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"]},"@openzeppelin/contracts/utils/Context.sol":{"keccak256":"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7","license":"MIT","urls":["bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92","dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3"]},"@openzeppelin/contracts/utils/Counters.sol":{"keccak256":"0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1","license":"MIT","urls":["bzz-raw://59e1c62884d55b70f3ae5432b44bb3166ad71ae3acd19c57ab6ddc3c87c325ee","dweb:/ipfs/QmezuXg5GK5oeA4F91EZhozBFekhq5TD966bHPH18cCqhu"]},"@openzeppelin/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","license":"MIT","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"]},"@openzeppelin/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","license":"MIT","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"]},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","license":"MIT","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"]},"@openzeppelin/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","license":"MIT","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"]},"@openzeppelin/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","license":"MIT","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"]},"base64-sol/base64.sol":{"keccak256":"0xa73959e6ef0b693e4423a562e612370160b934a75e618361ddd8c9c4b8ddbaaf","license":"MIT","urls":["bzz-raw://17c12e16d8d66f3af15d8787920bd41ca6c1e7517a212a6b9cebd4b6d38f36fe","dweb:/ipfs/QmcXMnZUXEz6LRKsm3CSvqdPboAzmezavi8bTg2dRxM2yE"]},"contracts/TestDappCollectibles.sol":{"keccak256":"0x3d2fa0d37970b903e628d8a7b101f8f73513d41d917fbdfac2749d9d1214176c","license":"MIT","urls":["bzz-raw://e01f3a25371accdfbbc2e3c9aeceabf92c5158f318a5e3f5b6c2b6ea3edb0c3b","dweb:/ipfs/QmT89aSnmzTdpRpoCoqCmnrR3Lp7CyXFtpnn2P52YEJULD"]}},"version":1}',
    },
  ],
};

async function mockedSourcifyResponse(mockServer: MockttpServer) {
  return await mockServer
    .forGet(
      'https://sourcify.dev/server/files/any/1337/0x581c3c1a2a4ebde2a0df29b5cf4c116e42945947',
    )
    .always()
    .thenCallback(() => {
      return {
        statusCode: 200,
        json: SOURCIFY_RESPONSE,
      };
    });
}

async function mockTokensAndInfura(mockServer: MockttpServer) {
  return [await mockInfura(mockServer), await mockWethAndUsdcToken(mockServer)];
}

async function mockWethAndUsdcToken(mockServer: MockttpServer) {
  return await mockServer
    .forGet('https://token.api.cx.metamask.io/tokens/1')
    .thenCallback(() => {
      return {
        statusCode: 200,
        json: [
          {
            address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
            symbol: 'WETH',
            decimals: 18,
            name: 'Wrapped Ether',
            iconUrl: '',
            aggregators: [],
            occurrences: 1,
          },
          {
            address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
            symbol: 'USDC',
            decimals: 6,
            name: 'USDC',
            iconUrl: '',
            aggregators: [],
            occurrences: 1,
          },
        ],
      };
    });
}

async function mockInfura(mockServer: MockttpServer) {
  return await mockServer
    .forPost()
    .withJsonBodyIncluding({
      method: 'eth_getCode',
      params: ['0xef1c6e67703c7bd7107eed8303fbe6ec2554bf6b'],
    })
    .thenCallback(() => {
      return {
        statusCode: 200,
        json: {
          jsonrpc: '2.0',
          id: '1',
          result:
            '0x6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c90816301ffc9a7146100be57508063150b7a02146100b557806324856bc3146100ac5780633593564c146100a3578063709a1cc21461009a578063bc197c8114610091578063f23a6e61146100885763fa461e330361000e576100836109f2565b61000e565b50610083610960565b50610083610898565b5061008361061d565b50610083610473565b506100836102c5565b50610083610202565b346101ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101ae57600435907fffffffff0000000000000000000000000000000000000000000000000000000082168092036101ae57507f4e2312e0000000000000000000000000000000000000000000000000000000008114908115610184575b811561015a575b50151560805260206080f35b7f01ffc9a7000000000000000000000000000000000000000000000000000000009150148161014e565b7f150b7a020000000000000000000000000000000000000000000000000000000081149150610147565b80fd5b73ffffffffffffffffffffffffffffffffffffffff8116036101cf57565b600080fd5b9181601f840112156101cf5782359167ffffffffffffffff83116101cf57602083818601950101116101cf57565b50346101cf5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf5761023d6004356101b1565b6102486024356101b1565b60643567ffffffffffffffff81116101cf576102689036906004016101d4565b505060206040517f150b7a02000000000000000000000000000000000000000000000000000000008152f35b9181601f840112156101cf5782359167ffffffffffffffff83116101cf576020808501948460051b0101116101cf57565b506040807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf5767ffffffffffffffff600480358281116101cf5761031290369083016101d4565b90926024359081116101cf5761032b9036908401610294565b9490916001958680540361044b57600287558181036104235760005b8281106103575761001960018055565b61038b61036582858a610bde565b357fff000000000000000000000000000000000000000000000000000000000000001690565b6103a96103a361039c84868a610bf6565b3691610daf565b82611590565b91901590816103f8575b506103c057508701610347565b6103f4879186519384937f2c4029e90000000000000000000000000000000000000000000000000000000085528401610e4c565b0390fd5b7f800000000000000000000000000000000000000000000000000000000000000091501615386103b3565b8483517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b8483517f6f5ffb7e000000000000000000000000000000000000000000000000000000008152fd5b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf57600467ffffffffffffffff81358181116101cf576104bf90369084016101d4565b9290916024359081116101cf576104d99036908301610294565b9360443542116105f457600194858054036105cb57600286558181036105a25760005b82811061050c5761001960018055565b61051a610365828589610bde565b61052b6103a361039c848689610bf6565b9190159081610577575b50610542575086016104fc565b6103f486916040519384937f2c4029e90000000000000000000000000000000000000000000000000000000085528401610e4c565b7f80000000000000000000000000000000000000000000000000000000000000009150161538610535565b836040517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b836040517f6f5ffb7e000000000000000000000000000000000000000000000000000000008152fd5b826040517f5bf6f916000000000000000000000000000000000000000000000000000000008152fd5b50346101cf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf5760043567ffffffffffffffff81116101cf5761066e9036906004016101d4565b604092919251928380610686600096879586956124c1565b0390827f0000000000000000000000000554f068365ed43dcc98dcd7fd7a8208a5638c725af16106b4610f1d565b501561086e576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f1e8f03f716bc104bf7d728131967a0c771e85ab54d09c1e2d6ed9e0bc4e2a16c916107f1919073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f4d2888d29d722226fafa5d9b24f9164c092421e168183602481845afa928315610861575b8693610832575b506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000ea37093ce161f090e443f304e1bf3a8f14d7bb4073ffffffffffffffffffffffffffffffffffffffff16600482015260248101849052908290829060449082908a905af18015610825575b6107f7575b50506040519081529081906020820190565b0390a180f35b8161081692903d1061081e575b61080e8183610d25565b8101906124cf565b5038806107df565b503d610804565b61082d610f89565b6107da565b610853919350823d841161085a575b61084b8183610d25565b810190610f7a565b913861075b565b503d610841565b610869610f89565b610754565b60046040517f7d529919000000000000000000000000000000000000000000000000000000008152fd5b50346101cf5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf576108d36004356101b1565b6108de6024356101b1565b67ffffffffffffffff6044358181116101cf576108ff903690600401610294565b50506064358181116101cf57610919903690600401610294565b50506084359081116101cf576109339036906004016101d4565b50506040517fbc197c81000000000000000000000000000000000000000000000000000000008152602090f35b50346101cf5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf5761099b6004356101b1565b6109a66024356101b1565b60843567ffffffffffffffff81116101cf576109c69036906004016101d4565b505060206040517ff23a6e61000000000000000000000000000000000000000000000000000000008152f35b50346101cf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cf5760243560043560443567ffffffffffffffff81116101cf57610a489036906004016101d4565b919060009384831393841580610ba4575b610b7a5782610a6d91610a9a940190613b49565b73ffffffffffffffffffffffffffffffffffffffff80911692610a8f83613bcb565b818398929a93614167565b8333911603610b505715610b425750808616908416105b15610ac65750610ac3935033916131e0565b80f35b915091604282511015600014610b0157610afb9350610ae482613c58565b610af6610af133926143d8565b613b90565b614014565b50505080f35b9192905083548211610b1857610ac39233916131e0565b60046040517f739dbe52000000000000000000000000000000000000000000000000000000008152fd5b945080841690861610610ab1565b60046040517f32b13d91000000000000000000000000000000000000000000000000000000008152fd5b60046040517f316cf0eb000000000000000000000000000000000000000000000000000000008152fd5b5085821315610a59565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90821015610bea570190565b610bf2610bae565b0190565b9190811015610c57575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1813603018212156101cf57019081359167ffffffffffffffff83116101cf5760200182360381136101cf579190565b610c5f610bae565b610c00565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6080810190811067ffffffffffffffff821117610cb057604052565b610cb8610c64565b604052565b6060810190811067ffffffffffffffff821117610cb057604052565b67ffffffffffffffff8111610cb057604052565b6020810190811067ffffffffffffffff821117610cb057604052565b6040810190811067ffffffffffffffff821117610cb057604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610cb057604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610da2575b01160190565b610daa610c64565b610d9c565b929192610dbb82610d66565b91610dc96040519384610d25565b8294818452818301116101cf578281602093846000960137010152565b60005b838110610df95750506000910152565b8181015183820152602001610de9565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093610e4581518092818752878088019101610de6565b0116010190565b604090610e63939281528160208201520190610e09565b90565b91908260809103126101cf578151610e7d816101b1565b916020810151610e8c816101b1565b916060604083015192015190565b81601f820112156101cf578051610eb081610d66565b92610ebe6040519485610d25565b818452602082840101116101cf57610e639160208085019101610de6565b9190916040818403126101cf57805192602082015167ffffffffffffffff81116101cf57610e639201610e9a565b60405190610f1782610ced565b60008252565b3d15610f48573d90610f2e82610d66565b91610f3c6040519384610d25565b82523d6000602084013e565b606090565b908160609103126101cf578051610f63816101b1565b9160406020830151610f74816101b1565b92015190565b908160209103126101cf575190565b506040513d6000823e3d90fd5b5190610fa1826101b1565b565b908160209103126101cf5751610e63816101b1565b908160609103126101cf5780519160406020830151610f74816101b1565b60405190610fe382610d09565b601782527f43727970746f50756e6b205472616465204661696c65640000000000000000006020830152565b60009103126101cf57565b60209067ffffffffffffffff8111611034575b60051b0190565b61103c610c64565b61102d565b9060209182818303126101cf5780519067ffffffffffffffff82116101cf570181601f820112156101cf578051926110788461101a565b9360409361108885519687610d25565b818652828087019260071b850101938185116101cf578301915b8483106110b25750505050505090565b6080838303126101cf578360809187516110cb81610c94565b85516110d6816101b1565b8152828601516110e5816101b1565b83820152888601516110f6816101b1565b898201526060808701519061110a826101b1565b8201528152019201916110a2565b91908260409103126101cf5760208251610f74816101b1565b519065ffffffffffff821682036101cf57565b91908260809103126101cf5760405161115c81610c94565b606061119b818395805161116f816101b1565b8552602081015161117f816101b1565b602086015261119060408201611131565b604086015201611131565b910152565b91909180830360e081126101cf5760c0136101cf576040516111c181610cbd565b6111cb8483611144565b815260808201516111db816101b1565b602082015260a082015160408201529260c082015167ffffffffffffffff81116101cf57610e639201610e9a565b90610e63939260409173ffffffffffffffffffffffffffffffffffffffff809116845261127b60208501835160609073ffffffffffffffffffffffffffffffffffffffff80825116845260208201511660208401528165ffffffffffff91826040820151166040860152015116910152565b60208201511660a0840152015160c0820152610100908160e08201520190610e09565b519081151582036101cf57565b9160a0838303126101cf5782516112c1816101b1565b926020918282015193604083015193606084015167ffffffffffffffff81116101cf5784019180601f840112156101cf5782516112fd8161101a565b9361130b6040519586610d25565b818552838086019260051b8201019283116101cf578301905b82821061133c57505050506080610e6391930161129e565b838091835161134a816101b1565b815201910190611324565b9190916040818403126101cf5780519267ffffffffffffffff938481116101cf578201936060858303126101cf5760405161138f81610cbd565b85518281116101cf5786019583601f880112156101cf578651966113b28861101a565b906113c06040519283610d25565b888252602098898084019160071b830101918783116101cf578a809101915b83831061141b57505050509060409183526113fb888201610f96565b8884015201516040820152948301519081116101cf57610e639201610e9a565b906080916114298a85611144565b8152019101908a906113df565b939290919373ffffffffffffffffffffffffffffffffffffffff809316815260209460608683015260c082019381519460608085015285518091528760e0850196019060005b8181106114ac5750505090604091610e639697820151166080840152015160a08201526040818403910152610e09565b909196896080826115016001948c5160609073ffffffffffffffffffffffffffffffffffffffff80825116845260208201511660208401528165ffffffffffff91826040820151166040860152015116910152565b01980192910161147c565b908160609103126101cf578051611522816101b1565b9160406020830151611533816101b1565b920151610e63816101b1565b919060a0838203126101cf578251611556816101b1565b9260208101519260408201519260608301519067ffffffffffffffff82116101cf57611589608091610e63938601610e9a565b930161129e565b600192606092909160f81c601f166010811015611b085760088110156118aa578061161957506115cc81602080610fa19451830101910161153f565b909290156115fa576115f573ffffffffffffffffffffffffffffffffffffffff33955b166124e3565b613d69565b6115f573ffffffffffffffffffffffffffffffffffffffff30956115ef565b60018103611684575061163881602080610fa19451830101910161153f565b909290156116655761166073ffffffffffffffffffffffffffffffffffffffff3395166124e3565b613efb565b61166073ffffffffffffffffffffffffffffffffffffffff30956115ef565b600281036116c557506116a381602080610fa19451830101910161150c565b9173ffffffffffffffffffffffffffffffffffffffff80921691339116612ce5565b600381036117925750806020806116e193518301019101611355565b9073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31691823b156101cf5761175f92600092836040518096819582947f2a2d80d10000000000000000000000000000000000000000000000000000000084523360048501611436565b03925af18015611785575b611772575b50565b8061177f610fa192610cd9565b8061100f565b61178d610f89565b61176a565b600481036117da57506117b181602080610fa194518301019101610f4d565b91906117d373ffffffffffffffffffffffffffffffffffffffff8092166124e3565b911661276b565b6005810361182257506117f981602080610fa194518301019101610f4d565b919061181b73ffffffffffffffffffffffffffffffffffffffff8092166124e3565b9116612514565b6006810361186a575061184181602080610fa194518301019101610f4d565b919061186373ffffffffffffffffffffffffffffffffffffffff8092166124e3565b9116612663565b9050600781146118775750565b6040517fd76a1e9e0000000000000000000000000000000000000000000000000000000081526004810191909152602490fd5b6008810361191557506118c981602080610fa1945183010191016112ab565b909290156118f6576118f173ffffffffffffffffffffffffffffffffffffffff3395166124e3565b612fbe565b6118f173ffffffffffffffffffffffffffffffffffffffff30956115ef565b60098103611980575061193481602080610fa1945183010191016112ab565b909290156119615761195c73ffffffffffffffffffffffffffffffffffffffff3395166124e3565b61387e565b61195c73ffffffffffffffffffffffffffffffffffffffff30956115ef565b600a8103611a1a57508060208061199c935183010191016111a0565b9073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31691823b156101cf5761175f92600092836040518096819582947f2b67b5700000000000000000000000000000000000000000000000000000000084523360048501611209565b600b8103611a5d575073ffffffffffffffffffffffffffffffffffffffff611a58611a5183602080610fa196518301019101611118565b92166124e3565b612a14565b600c8103611a99575073ffffffffffffffffffffffffffffffffffffffff611a94611a5183602080610fa196518301019101611118565b612baf565b600d8103611abd5750611ab881602080610fa194518301019101611041565b612e78565b92919050600e8303611afb576040517fd76a1e9e00000000000000000000000000000000000000000000000000000000815260048101849052602490fd5b9091600f81146118775750565b919290916018811015611ffd5760108103611b6f5750506000919250611b38816020808594518301019101610edc565b90602082519201907f00000000000000000000000000000000006c3852cbef3e08e8df289169ede5815af1611b6b610f1d565b9091565b60118103611ba6575050611b6b9192507f00000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a906121e6565b60128103611bfc5750506000919250611bc9816020808594518301019101610edc565b90602082519201907f0000000000000000000000000fc584529a2aefa997697fafacba5831fac0c22d5af1611b6b610f1d565b60138103611d61575050611c1b91925060208082518301019101610fb8565b9290927f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb9260405160208101907f8264fe98000000000000000000000000000000000000000000000000000000008252611cad81611c8185602483019190602083019252565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610d25565b600093849283925191885af194611cc2610f1d565b948615611d5357611cec9073ffffffffffffffffffffffffffffffffffffffff80911692166124e3565b813b15611d4f576040517f8b72a2ec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481019290925290919082908183816044810161175f565b8380fd5b505050509050610e63610fd6565b60148103611d98575050611b6b9192507f00000000000000000000000059728544b08ab483533076417fbbb2fd0b17ce3a90612386565b9092919060158103611eae5750611dc19350611dfc906020948186808094518301019101610f4d565b604093919351809581927f6352211e000000000000000000000000000000000000000000000000000000008352600483019190602083019252565b038173ffffffffffffffffffffffffffffffffffffffff8096165afa928315611ea1575b600093611e70575b508116911614928315611e385750565b9091507f7dbe7e89000000000000000000000000000000000000000000000000000000006040519182015260048152610e6381610d09565b82919350611e9390873d8911611e9a575b611e8b8183610d25565b810190610fa3565b9290611e28565b503d611e81565b611ea9610f89565b611e20565b60168103611fb45750611ed29350611f306020948286808095518301019101610e66565b6040517efdd58e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff94851660048201526024810192909252949093909284929183919082906044820190565b0392165afa908115611fa7575b600091611f8a575b501092831593611f525750565b9091507f483a6929000000000000000000000000000000000000000000000000000000006040519182015260048152610e6381610d09565b611fa19150853d871161085a5761084b8183610d25565b38611f45565b611faf610f89565b611f3d565b601714611fbe5750565b611fd481602080610fa194518301019101610f4d565b9190611ff673ffffffffffffffffffffffffffffffffffffffff8092166124e3565b9116612888565b60188103612034575050611b6b9192507f00000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed3906121e6565b6019810361208a5750506000919250612057816020808594518301019101610edc565b90602082519201907f0000000000000000000000002b2e8cda09bba9660dca5cb6233787738ad683295af1611b6b610f1d565b601a81036120e057505060009192506120ad816020808594518301019101610edc565b90602082519201907f000000000000000000000000a42f6cada809bcf417deefbdd69c5c5a909249c05af1611b6b610f1d565b601b8103612117575050611b6b9192507f00000000000000000000000074312363e45dcaba76c59ec49a7aa8a65a67eed390612386565b601c810361214e575050611b6b9192507f000000000000000000000000cda72070e455bb31c7690a170224ce43623d0b6f906121e6565b90929190601d810361219b575061217181602080610fa194518301019101610e66565b92909161219473ffffffffffffffffffffffffffffffffffffffff8092166124e3565b9116612928565b92919050601e83036121d9576040517fd76a1e9e00000000000000000000000000000000000000000000000000000000815260048101849052602490fd5b9091601f81146118775750565b9091815182019260a0838503126101cf57602083015193604084015167ffffffffffffffff81116101cf57602080612222930191860101610e9a565b90606084015194612232866101b1565b60a0608086015195612243876101b1565b01519173ffffffffffffffffffffffffffffffffffffffff8096169160009485928392602083519301915af195612278610f1d565b9587612286575b5050505050565b61229091166124e3565b813b15611d4f576040517f42842e0e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91909116602482015260448101929092529091908290606490829084905af1801561231f575b61230c575b8080808061227f565b8061177f61231992610cd9565b38612303565b612327610f89565b6122fe565b60405161233881610ced565b60008152906000368137565b9192610e6395949160a09473ffffffffffffffffffffffffffffffffffffffff8092168552166020840152604083015260608201528160808201520190610e09565b9091815182019160c0818403126101cf57602081015192604082015167ffffffffffffffff81116101cf576020806123c2930191840101610e9a565b6060820151946123d1866101b1565b6080830151946123e0866101b1565b60c060a08501519401519173ffffffffffffffffffffffffffffffffffffffff8097169160009485928392602083519301915af19661241d610f1d565b968861242c575b505050505050565b61243691166124e3565b9361243f61232c565b94823b156124bd578490612483604051978896879586947ff242432a0000000000000000000000000000000000000000000000000000000086523060048701612344565b03925af180156124b0575b61249d575b8080808080612424565b8061177f6124aa92610cd9565b38612493565b6124b8610f89565b61248e565b8480fd5b908092918237016000815290565b908160209103126101cf57610e639061129e565b73ffffffffffffffffffffffffffffffffffffffff8116600181036125085750503390565b600203610e6357503090565b73ffffffffffffffffffffffffffffffffffffffff1691908261253b57610fa192506142b9565b610fa1927f800000000000000000000000000000000000000000000000000000000000000083036143275791506040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152602081602481865afa9081156125d2575b6000916125b4575b5091614327565b6125cc915060203d811161085a5761084b8183610d25565b386125ad565b6125da610f89565b6125a5565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181029291811591840414171561262257565b610fa16125df565b8115612634570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b82158015612760575b6127365773ffffffffffffffffffffffffffffffffffffffff16806126aa57506126a461269c610fa1934761260f565b612710900490565b906142b9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610fa1939192916127059161269c9190602081602481895afa908115612729575b60009161270b575b5061260f565b91614327565b612723915060203d811161085a5761084b8183610d25565b386126ff565b612731610f89565b6126f7565b60046040517fdeaa01e6000000000000000000000000000000000000000000000000000000008152fd5b50612710831161266c565b90919073ffffffffffffffffffffffffffffffffffffffff16806127ce5750479081106127a4578061279b575050565b610fa1916142b9565b60046040517f6a12f104000000000000000000000000000000000000000000000000000000008152fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290929091602083602481875afa92831561287b575b60009361285b575b508210612831578161282857505050565b610fa192614327565b60046040517f675cae38000000000000000000000000000000000000000000000000000000008152fd5b61287491935060203d811161085a5761084b8183610d25565b9138612817565b612883610f89565b61280f565b73ffffffffffffffffffffffffffffffffffffffff1691823b156101cf576040517f42842e0e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff9290921660248301526044820152906000908290606490829084905af1801561291b575b6129125750565b610fa190610cd9565b612923610f89565b61290b565b6040517efdd58e00000000000000000000000000000000000000000000000000000000815230600482015260248101849052929391929173ffffffffffffffffffffffffffffffffffffffff9190911690602083604481855afa928315612a07575b6000936129e7575b508210612831576129a1610f0a565b93813b156101cf576000809461175f604051978896879586947ff242432a0000000000000000000000000000000000000000000000000000000086523060048701612344565b612a0091935060203d811161085a5761084b8183610d25565b9138612992565b612a0f610f89565b61298a565b907f80000000000000000000000000000000000000000000000000000000000000008103612b7c575047905b81612a49575050565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21691823b156101cf57612b26926020926040517fd0e30db000000000000000000000000000000000000000000000000000000000815260008160048187875af18015612b6f575b612b5c575b5060006040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af18015612b4f575b612b385750565b61176f9060203d811161081e5761080e8183610d25565b612b57610f89565b612b31565b8061177f612b6992610cd9565b38612acb565b612b77610f89565b612ac6565b9047821115612a405760046040517f6a12f104000000000000000000000000000000000000000000000000000000008152fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21692909190602083602481875afa928315612cd8575b600093612cb8575b5082106127a45781612c4057505050565b823b156101cf576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815260048101839052610fa1936000908290602490829084905af18015612cab575b612c98575b506142b9565b8061177f612ca592610cd9565b38612c92565b612cb3610f89565b612c8d565b612cd191935060203d811161085a5761084b8183610d25565b9138612c2f565b612ce0610f89565b612c27565b919273ffffffffffffffffffffffffffffffffffffffff91827f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31693843b156101cf5760009484869281608496816040519b8c9a8b997f36c78516000000000000000000000000000000000000000000000000000000008b521660048a01521660248801521660448601521660648401525af1801561291b576129125750565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612db3570190565b610bf26125df565b602090805115610bea570190565b604090805160011015610bea570190565b6020918151811015612def575b60051b010190565b612df7610bae565b612de7565b60208082019080835283518092528060408094019401926000905b838210612e2657505050505090565b8451805173ffffffffffffffffffffffffffffffffffffffff90811688528185015181168886015281830151811688840152606091820151169087015260809095019493820193600190910190612e17565b805160005b818110612f0257505073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba316803b156101cf5761175f6000929183926040519485809481937f0d58b1db00000000000000000000000000000000000000000000000000000000835260048301612dfc565b33612f47612f2e612f138487612dda565b515173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1690565b03612f5a57612f5590612d85565b612e7d565b60046040517fe7002877000000000000000000000000000000000000000000000000000000008152fd5b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820191821161262257565b9190820391821161262257565b61312893919294613042612fee612fd485612dbb565b5173ffffffffffffffffffffffffffffffffffffffff1690565b612ffa612fd486612dc9565b907f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f61324a565b9384816131c3575b505050613069612f2e612f2e612fd46130638651612f84565b86612dda565b6040517f70a082310000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff8416600483015290946020948587602481875afa9687156131b6575b600097613183575b50916130dc8694928661310d9795613452565b60405180958194829383526004830191909173ffffffffffffffffffffffffffffffffffffffff6020820193169052565b03915afa918215613176575b600092613159575b5050612fb1565b1061312f57565b60046040517f849eaf98000000000000000000000000000000000000000000000000000000008152fd5b61316f9250803d1061085a5761084b8183610d25565b3880613121565b61317e610f89565b613119565b859391975086949261310d966131a86130dc93883d8a1161085a5761084b8183610d25565b9993955096509294506130c9565b6131be610f89565b6130c1565b6131d8926131d3612fd487612dbb565b6131e0565b38808461304a565b92919073ffffffffffffffffffffffffffffffffffffffff808216300361320c575050610fa192612514565b808495941161322057610fa1941692612ce5565b60046040517fc4bd89a9000000000000000000000000000000000000000000000000000000008152fd5b9091610e6393613259916133a4565b9290915b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa06133909161336373ffffffffffffffffffffffffffffffffffffffff96946040519260208401967fffffffffffffffffffffffffffffffffffffffff000000000000000000000000809260601b16885260601b16603484015260288352606083019583871067ffffffffffffffff881117613397575b8660405283519020608084019788917fffffffffffffffffffffffffffffffffffffffff000000000000000000000000605594927fff00000000000000000000000000000000000000000000000000000000000000855260601b166001840152601583015260358201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80810184520182610d25565b5190201690565b61339f610c64565b6132f5565b73ffffffffffffffffffffffffffffffffffffffff8281169082161015611b6b5791565b51906dffffffffffffffffffffffffffff821682036101cf57565b908160609103126101cf576133f7816133c8565b916040613406602084016133c8565b92015163ffffffff811681036101cf5790565b90610e63949360809373ffffffffffffffffffffffffffffffffffffffff92845260208401521660408201528160608201520190610e09565b90600292838351106137945761347f61346d612fd485612dbb565b613479612fd486612dc9565b906133a4565b508351937ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86019501906000935b8685106134df575050505050505050565b6134ec612fd48684612dda565b906134fd612fd46001880185612dda565b73ffffffffffffffffffffffffffffffffffffffff928383169660409081519485937f0902f1ac00000000000000000000000000000000000000000000000000000000855260609788868d60049889915afa978815613787575b6000998a99613748575b50508061360695969798996dffffffffffffffffffffffffffff8091169a16921693168314978860001461373e57918291935b87875180927f70a0823100000000000000000000000000000000000000000000000000000000825281806135ea6020978896830191909173ffffffffffffffffffffffffffffffffffffffff6020820193169052565b03915afa918215613731575b600092613714575b5050036137d7565b931561370b578a600094935b878a10156137005761362c612fd4613674938c0189612dda565b907f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f6137be565b9390935b9761368161232c565b95813b156101cf57600086956136c7600199839751988997889687957f022c0d9f0000000000000000000000000000000000000000000000000000000087528601613419565b03925af180156136f3575b6136e0575b509401936134ce565b8061177f6136ed92610cd9565b386136d7565b6136fb610f89565b6136d2565b505088926000613678565b8a600093613612565b61372a9250803d1061085a5761084b8183610d25565b38806135fe565b613739610f89565b6135f6565b9091829193613594565b829a506136069697989950908161377392903d10613780575b61376b8183610d25565b8101906133e3565b5099909998979695613561565b503d613761565b61378f610f89565b613557565b60046040517fae52ad0c000000000000000000000000000000000000000000000000000000008152fd5b926137cc906137d4936133a4565b91819461325d565b91565b811590818015613876575b61384c57613808610e63946103e59283810293818504149015171561383f575b8261260f565b916103e8808502948504141715613832575b82018092111561262a575b61382d6125df565b61262a565b61383a6125df565b61381a565b6138476125df565b613802565b60046040517f7b9c8916000000000000000000000000000000000000000000000000000000008152fd5b5083156137e2565b91939290927f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f947f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f9560009560028551106139d257968451917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff928381019081116139c5575b929190835b61395b5750505050851161393157610fa1948461392c926131d3612fd486612dbb565b613452565b60046040517f8ab0bc16000000000000000000000000000000000000000000000000000000008152fd5b929897509091826139996139928b61398a612fd4613983818488018e8682116139b857612dda565b928c612dda565b9086866139fc565b919b613abc565b9980156139ab575b0192919083613909565b6139b36125df565b6139a1565b6139c06125df565b612dda565b6139cd6125df565b613904565b60046040517f20db8267000000000000000000000000000000000000000000000000000000008152fd5b919392906137cc613a0d92866133a4565b92604051907f0902f1ac00000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff606083600481848a165afa928315613aaf575b6000908194613a8d575b5081906dffffffffffffffffffffffffffff80911694169416911614600014611b6b5791565b829450613aa8915060603d81116137805761376b8183610d25565b5093613a67565b613ab7610f89565b613a5d565b909182158015613b41575b61384c57613ad882613b119461260f565b906103e891828102928184041490151715613b34575b82810392818411613b27575b6103e580850294850414911417156138255761262a565b60018101809111613b1f5790565b610e636125df565b613b2f6125df565b613afa565b613b3c6125df565b613aee565b508015613ac7565b91906040838203126101cf57823567ffffffffffffffff81116101cf57830181601f820112156101cf576020918183613b8493359101610daf565b920135610e63816101b1565b7f80000000000000000000000000000000000000000000000000000000000000008114613bbe575b60000390565b613bc66125df565b613bb8565b908151613bd88184613c49565b9260178210613c1f57602b60178201519210613bf557602b015191565b60046040517fa78aa27f000000000000000000000000000000000000000000000000000000008152fd5b60046040517fd9096a3e000000000000000000000000000000000000000000000000000000008152fd5b90601411613bf5576014015190565b8051907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe99182810192818411613d5c575b836008830110613d325760178210613d325781835110613d085760178214613cde57601f8416801560051b0183019182010160178201915b818110613cce5750505052565b8251815260209283019201613cc1565b60046040517fcc94a63a000000000000000000000000000000000000000000000000000000008152fd5b60046040517f3b99b53d000000000000000000000000000000000000000000000000000000008152fd5b60046040517f47aaf07a000000000000000000000000000000000000000000000000000000008152fd5b613d646125df565b613c89565b93909192937f80000000000000000000000000000000000000000000000000000000000000008314613e34575b90613dc5613dd3915b613dae604288511015956143d8565b8515613e2e57305b613dbf89613ecd565b91614126565b90919015613e275750613b90565b9115613df357613dc5613dd3913090613deb87613c58565b929190613d9f565b50109050613dfd57565b60046040517f39d35496000000000000000000000000000000000000000000000000000000008152fd5b9050613b90565b84613db6565b9150613dc5613dd391613e4e612f2e612f2e885189613c49565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290602090829060249082905afa908115613ec0575b600091613ea2575b509391509150613d96565b613eba915060203d811161085a5761084b8183610d25565b38613e97565b613ec8610f89565b613e8f565b90602b825110613d0857602b60405192600b810151600b8501520151602b830152602b825260608201604052565b613f1193919492600055610af6610af1866143d8565b90919015613f785750613f2390613b90565b03613f4e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055565b60046040517fd4e0248e000000000000000000000000000000000000000000000000000000008152fd5b613f829150613b90565b613f23565b9073ffffffffffffffffffffffffffffffffffffffff613fb4602092959495604085526040850190610e09565b9416910152565b91908260409103126101cf576020825192015190565b919360a093610e63969573ffffffffffffffffffffffffffffffffffffffff80941685521515602085015260408401521660608201528160808201520190610e09565b612f2e9293612f2e60006040946140b26140596140308a613bcb565b73ffffffffffffffffffffffffffffffffffffffff9b9297919b808916908d16109b8c98614167565b948484146141085761407d6401000276a49a5b611c818a5193849260208401613f87565b8751998a97889687957f128acb0800000000000000000000000000000000000000000000000000000000875260048701613fd1565b03925af180156140fb575b60009283916140cb57509192565b90506140ef91925060403d81116140f4575b6140e78183610d25565b810190613fbb565b919092565b503d6140dd565b614103610f89565b6140bd565b61407d73fffd8963efd1fc6a506488495d951d5263988d259a61406c565b612f2e9293612f2e60006040946140b26140596141428a613bcb565b73ffffffffffffffffffffffffffffffffffffffff9b9297919b808d16908916109b8c985b73ffffffffffffffffffffffffffffffffffffffff92838316848316116142b1575b62ffffff908460405194816020870195168552166040850152166060830152606082526133907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80608084019284841067ffffffffffffffff8511176142a4575b6040849052845190207fff0000000000000000000000000000000000000000000000000000000000000060a086019081527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f98460601b1660a187015260b58601919091527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460d5909501949094526055835260f50182610d25565b6142ac610c64565b6141e9565b909190614189565b600080809381935af1156142c957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152fd5b60009182604492602095604051937fa9059cbb000000000000000000000000000000000000000000000000000000008552600485015260248401525af13d15601f3d116001600051141617161561437a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b7f80000000000000000000000000000000000000000000000000000000000000008110156101cf579056fea26469706673582212202f2e114dd73237126f72d60b80c2baf2d9fc70c6d00948608ca4fefdc9bf009064736f6c63430008110033',
        },
      };
    });
}
